#include "alphabeta_player.hpp"
#include <iostream>
#include <algorithm>

AlphabetaPlayer::AlphabetaPlayer(const Camp camp, const int max_depth): _max_depth(max_depth), _camp(camp) { }

Move AlphabetaPlayer::decide(Board board) {
    if(board.side() != _camp) board.rotate();
    Move maxm;
    int maxw = _MIN_VALUE;
    auto all_move = board.available_move();
    for(auto &m: all_move) {
        int w = get_weight(board, m, 1, true, maxw, _MAX_VALUE);
        if(w > maxw) {
            maxm = m;
            maxw = w;
        }
    }
    if(maxw == _MIN_VALUE)
        return all_move[0];
    else
        return maxm;
}

void AlphabetaPlayer::win() {

}

void AlphabetaPlayer::lose() {

}

int AlphabetaPlayer::get_weight(Board &board, const Move &m, const int depth, bool self, int alpha, int beta) {
    // self表示父节点是否为max节点
    board.move(m);
    Camp winner;
    if(board.judge(winner)) {
        board.undo();
        return winner == _camp ? _MAX_VALUE : _MIN_VALUE;
    }
    if(depth < _max_depth) {
        board.rotate();
        self = !self;
        Move bestm;
        int bestw = self ? _MIN_VALUE : _MAX_VALUE;
        for(auto &nxt: board.available_move()) {
            if(self) {
                // max
                int w = get_weight(board, nxt, depth + 1, self, std::max(alpha, bestw), beta);
                if(w > bestw) {
                    bestm = nxt;
                    bestw = w;
                }
                if(w >= beta) break;
            } else {
                // min
                int w = get_weight(board, nxt, depth + 1, self, alpha, std::min(beta, bestw));
                if(w < bestw) {
                    bestm = nxt;
                    bestw = w;
                }
                if(w <= alpha) break;
            }
        }
        board.undo();
        board.rotate();
        return bestw;
    } else {
        int v = value(board);
        board.undo();
        return v;
    }
}

int AlphabetaPlayer::value(const Board &board) {
    return board.count(_camp) - board.count(!_camp);
}